#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int argc, const char *argv[]) {
    // 创建套接字
    if (argc != 2) {
        printf("输入参数错误 exe port\n");
        exit(-1);
    }
    
    // 创建套接字，AF_INET表示IPv4地址家族，SOCK_STREAM表示流式套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("fail to socket\n");
        exit(-1);
    }
    printf("socket创建成功！\n");
    
    // 绑定
    struct sockaddr_in saddr;
    struct sockaddr_in caddr;
    socklen_t caddrlen = sizeof(caddr);
    memset(&caddr, 0, sizeof(caddr));
    memset(&saddr, 0, sizeof(saddr));

    saddr.sin_family = AF_INET;  // 使用IPv4地址
    saddr.sin_port = htons(atoi(argv[1]));  // 将主机字节序端口转换为网络字节序
    saddr.sin_addr.s_addr = INADDR_ANY;  // 绑定到所有网络接口上的任何IP地址
    int ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
    if (ret == -1) {
        perror("fail to bind!\n");
        exit(-1);
    }
    printf("绑定成功！\n");
    
    // 监听连接请求
    ret = listen(sockfd, 10);
    if (ret == -1) {
        perror("fail to listen\n");
        exit(-1);
    }
    printf("监听成功！\n");

    // 循环接收客户端连接和处理请求
    while (1) {
        // 接受客户端连接请求
        int connfd = accept(sockfd, (struct sockaddr *)&caddr, &caddrlen);
        if (connfd == -1) {
            close(sockfd);
            exit(-1);
        }
        
        printf("连接成功！\n");
        printf("客户端 %s:%d 连接\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));  // 显示客户端连接信息
        
        char buf[1024] = {0};
        while (1) {
            memset(buf, 0, sizeof(buf));

            // 读取客户端发送的数据
            int len = read(connfd, buf, sizeof(buf));
            if (len == -1 || len == 0) {
                printf("客户端断开\n");
                break;
            }
            if (strncmp(buf, "quit", 4) == 0) {
                printf("客户端退出\n");
                break;
            }
            printf("读取 %d 字节 : %s\n", len, buf);
        }
        
        close(connfd);  // 关闭连接套接字
    }
    
    close(sockfd);  // 关闭监听套接字
    return 0;
}